package com.exchange.util;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author 李书文
 * @description 数据库参数拼接工具
 * @time 2016年10月21日
 */

public class SQL {

	private String select; // select语句
	private String fromClause; // from子句
	private StringBuffer whereClause = new StringBuffer(""); // where子句
	private StringBuffer orderByClause = new StringBuffer(""); // order by子句

	private List<Object> parameters = new ArrayList<Object>(); // 参数列表

	/**
	 * 用于一张表的情况，生成From子句
	 * 
	 * from topic t
	 */
	public SQL(String select, String tableName, String alias) {
		this.select = select;
		fromClause = new StringBuffer(" from ").append(tableName).append(" ").append(alias).toString();
	}

	/**
	 * 用于left join 这种可以写在一个from字句中
	 */
	public SQL(String select, String from) {
		this.select = select;
		fromClause = new StringBuffer(" from ").append(from).toString();
	}

	/**
	 * 用于两张表联合的情况，生成From子句，类似from table1 a,table2 b 然后添加where条件
	 * 这个方法的调用格式为("select...","table1","alias1","table2","alias2"...),至少两对，
	 * 如果只有一个表， 那就按照第一个构造方法调用 。后面的表和别名是一对一对出现的
	 */
	public SQL(String select, String[] table_alias) {
		if (table_alias.length <= 2 || table_alias.length % 2 != 0) {
			throw new RuntimeException("你的参数有误，请看该方法的说明");
		}
		this.select = select;
		StringBuffer buffer = new StringBuffer(" from ");

		int group = table_alias.length / 2;// 有这么多个表
		for (int i = 0; i < group; i++) {
			buffer.append(table_alias[i * 2]).append(" " + table_alias[i * 2 + 1]).append(",");
		}
		buffer.deleteCharAt(buffer.length() - 1);
		fromClause = buffer.toString();
	}

	/**
	 * 拼接where子句 d.id between ? and ? d.parent=? d.parent is null
	 * 
	 * @param condition
	 * @param params
	 */
	public SQL add(String condition, Object... params) {
		// 拼接
		if (whereClause.length() == 0) {
			whereClause = new StringBuffer(" where ").append(condition);
		} else {
			whereClause.append(" and ").append(condition);
		}

		// 参数
		if (params != null) {
			for (Object p : params) {
				parameters.add(p);
			}
		}

		return this;
	}

	/**
	 * 如果第一个参数为true，则拼接where子句
	 * 
	 * @param append
	 * @param condition
	 * @param params
	 */
	public SQL add(boolean append, String condition, Object... params) {
		if (append) {
			add(condition, params);
		}
		return this;
	}

	/**
	 * 拼接order by子句
	 * 
	 * @param propertyName
	 *            参与排序的属性名
	 * @param asc
	 *            true表示升序，false表示降序
	 */
	public SQL addOrderProperty(String propertyName, boolean asc) {
		if (orderByClause.length() == 0) {
			orderByClause = new StringBuffer(" order by ").append(propertyName + (asc ? " asc" : " desc"));
		} else {
			orderByClause.append(", ").append(propertyName + (asc ? " asc" : " desc"));
		}
		return this;
	}

	/**
	 * 如果第一个参数为true，则拼接order by子句
	 * 
	 * @param append
	 * @param propertyName
	 * @param asc
	 */
	public SQL addOrderProperty(boolean append, String propertyName, boolean asc) {
		if (append) {
			addOrderProperty(propertyName, asc);
		}
		return this;
	}

	public String getSelect() {
		return this.select;
	}

	/**
	 * 获取生成的用于查询数据列表的sqlExceptSelect语句
	 * 
	 * @return
	 */
	public String getSqlExceptSelect() {
		// 这里面含有一些?，下面来填充
		String sqlExceptSelect = new StringBuffer(fromClause).append(whereClause).append(orderByClause).toString();
		// 填充参数
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				// 巧妙利用替换一次之后，后面的?就自动往前移动一位，那么replaceFirst每次替换的就是下一个?
				sqlExceptSelect = sqlExceptSelect.replaceFirst("\\?", "'" + parameters.get(i) + "'");
			}
		}
		return sqlExceptSelect;
	}

	/**
	 * 获取生成的用于查询总记录数的SQL语句
	 * 
	 * @return
	 */
	public String getCountQuerySql() {
		return "select count(*) " + fromClause + whereClause;
	}

	/**
	 * 获取SQL中的参数值列表
	 * 
	 * @return
	 */
	public Object[] getParameters() {
		return parameters.toArray();
	}

	/**
	 * 获取生成的用于查询数据列表的sqlExceptSelect语句，里面可能含有?，需要配合getParameters
	 * 
	 * @return
	 */
	public String getSqlExceptSelectWithPadding() {
		// 这里面含有一些?，下面来填充
		String sqlExceptSelect = new StringBuffer(fromClause).append(whereClause).append(orderByClause).toString();
		return sqlExceptSelect;
	}

	public static void main(String[] args) {
		//String tables[]={"tb_admin ta","left join tb_user a on a.id=ta.id"};
		SQL sql = new SQL("select *", "tb_admin ta " + "left join tb_user a on a.id=ta.id");
		sql.add("barchId=" + "1111");
		sql.add("bas=" + "1111");
		sql.add("createTime between=" + "2016-10-21");
		sql.add("2016-10-21");
		sql.addOrderProperty(true, "id", false);
		System.out.println(sql.getSelect()+sql.getSqlExceptSelect());
      
	}
}
